package com.swallow.auth.domain.auth.service.impl;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.ShearCaptcha;
import com.swallow.auth.common.constants.RedisConstants;
import com.swallow.auth.domain.auth.model.*;
import com.swallow.auth.domain.auth.service.IAuthDomainService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;

/**
 * @author: 18310740596@163.com
 * @date: 2024-05-11 00:35:37
 * @version: v1.0
 * @describe: class responsibility
 */
@Slf4j
@Service
public class AuthDomainServiceImpl implements IAuthDomainService {

    @Resource private RedissonClient redissonClient;

    @Resource private RedisTemplate<String, Object> redisTemplate;

    @Override
    public void smsCaptcha(AuthRoot authRoot) {
        int captcha = ThreadLocalRandom.current().nextInt(100000, 999999);

        SmsValObj smsValObj = authRoot.getSmsValObj();

        SmsType smsByType = SmsType.findSmsByType(smsValObj.getSmsType());
        String cacheKey = RedisConstants.SMS_CAPTCHA_KEY.formatted(smsByType.getValue(), smsValObj.getMobile());
        redisTemplate.opsForValue().set(cacheKey, String.valueOf(captcha), 5, TimeUnit.MINUTES);

        smsValObj.sendRegisterSms(captcha);
    }

    @Override
    public AuthRoot pictureCaptcha() {
        // 使用huTool-captcha生成图形验证码
        // 定义图形验证码的长、宽、验证码字符数、干扰线宽度
        ShearCaptcha captcha = CaptchaUtil.createShearCaptcha(150, 40, 4, 3);
        // 生成一个唯一id
        String uniqId = UUID.randomUUID().toString().replaceAll("-", "");

        String cacheKey = RedisConstants.PIC_CAPTCHA_KEY.formatted(uniqId);
        // 有效期5分钟
        redisTemplate.opsForValue().set(cacheKey, captcha.getCode(), 5, TimeUnit.MINUTES);

        log.info("验证码ID:{} 验证码code:{}", uniqId, captcha.getCode());

        return AuthRoot.builder()
                       .captchaValObj(CaptchaValObj.builder()
                                                   .captchaId(uniqId)
                                                   .picture(captcha.getImageBase64Data())
                                                   .build())
                       .build();
    }

    @Override
    public String register(AuthRoot authRoot) {
        AccountEntity accountEntity = authRoot.getAccountEntity();

        // 签名验证
        // todo 密钥待规定
//        accountEntity.pwdSignCheck("", "");
        // 获取锁
        RLock lock = redissonClient.getLock(String.format(RedisConstants.ACCOUNT_REGISTER_UNIQUE_LOCK,
                                            accountEntity.getMobile(),
                                            accountEntity.getUsername())
                                           );
        lock.lock();
        try {
            accountEntity.registerInit();
            // 重复校校验
            accountEntity.dupCheck();
            // 验证码验证
            accountEntity.captchaCheck();
            // 密码强度校验
            accountEntity.pwdStrengthCheck();
            // 密码加密
            accountEntity.encryptPwd();
            // 账号创建
            accountEntity.create();
        } finally {
            lock.unlock();
        }

        return accountEntity.getAccountNo();
    }
}
